# AUTHOR : Felipe Ramos
# Code under MIT License

from tkinter import *
import hmac
import hashlib
import base64
import urllib.parse
import time

# GLOBAL VARIABLES
DAYSECONDS = 24*60*60

def generateUrl(filePath, publicKey, privateKey, reqPayment):
        # Separate bucket and file path from file path
        pos      = filePath.find("/") + 1
        filePath = filePath[pos:]
        pos      = filePath.find("/")
        bucket   = filePath[0:pos]
        filePath = filePath[pos:]
    
        # Make file path to compatible with all types of characters
        filePath = urllib.parse.quote(filePath)
    
        # URL valid for 24 hours
        expireTime = int(time.time()) + DAYSECONDS
        
        # Change the string to be encoded according to the request payment option set by the user
        if reqPayment == 0:
            stringToEncode = "GET\n\n\n" + str(expireTime) + "\n/" + bucket + filePath
        else :
            stringToEncode = "GET\n\n\n" + str(expireTime) + "\nx-amz-request-payer:requester" + "\n/" + bucket + filePath
        
        # Encode string using private key provided
        hash = hmac.new(privateKey.encode('utf8'), stringToEncode.encode('utf8'), hashlib.sha1)
        
        # Encode result to base64
        b64Output = base64.b64encode(hash.digest())
        
        # Quote final result
        signature = urllib.parse.quote(b64Output.decode('utf8'))
        
        # According to the request payment option, build the correct URL
        if reqPayment == 1:
            url = "http://" + bucket + ".s3.amazonaws.com" + filePath + "?AWSAccessKeyId=" + publicKey + "&Expires=" + str(expireTime) + "&x-amz-request-payer=requester" + "&Signature=" + signature
        else:
            url = "http://" + bucket + ".s3.amazonaws.com" + filePath + "?AWSAccessKeyId=" + publicKey + "&Expires=" + str(expireTime) + "&Signature=" + signature
    
        return url

class App:
    def __init__(self, master):
        # LINE 1
        self.line1 = Frame(master)
        self.line1.pack(side = TOP)
        
        self.title = Label(self.line1, text="S3 Address Generator")
        self.title.pack(side = TOP)

        self.publicKey = Label(self.line1, text="AWS Public Key")
        self.publicKey.configure(width=15)
        self.publicKey.pack(side = LEFT)
        
        self.publicKeyField = Entry(self.line1)
        self.publicKeyField.insert(0,"AWS Public Key")
        self.publicKeyField.configure(width=20)
        self.publicKeyField.pack(side = RIGHT)
        
        # LINE 2
        self.line2 = Frame(master)
        self.line2.pack(side = TOP)
        
        self.privateKey = Label(self.line2, text="AWS Private Key")
        self.privateKey.configure(width=15)
        self.privateKey.pack(side = LEFT)
        
        self.privateKeyField = Entry(self.line2)
        self.privateKeyField.insert(0,"AWS Private Key")
        self.privateKeyField.configure(width=20)
        self.privateKeyField.pack(side = RIGHT)
        
        # LINE 3
        self.line3 = Frame(master)
        self.line3.pack(side = TOP)
        
        self.filePath = Label(self.line3, text="File path")
        self.filePath.configure(width=15)
        self.filePath.pack(side = LEFT)
        
        self.filePathField = Entry(self.line3)
        self.filePathField.insert(0,"File path")
        self.filePathField.configure(width=20)
        self.filePathField.pack(side = RIGHT)
        
        # LINE 6
        self.line6 = Frame(master)
        self.line6.pack(side = TOP)
        
        self.checkRequestPaymentVar = IntVar()
        self.checkRequestPayment = Checkbutton(self.line6, text="Request Payment Bucket", variable=self.checkRequestPaymentVar)
        self.checkRequestPayment.configure(width=40)
        self.checkRequestPayment.pack(side = LEFT)
        
        # LINE 4
        self.line4 = Frame(master)
        self.line4.pack(side = TOP)
        
        self.btn = Button(self.line4, text="Generate URL (Valid for 24h)", command=self.generateUrlButton)
        self.btn.configure(width=30)
        self.btn.pack(side = LEFT)
        
        # LINE 5
        self.line5 = Frame(master)
        self.line5.pack(side = TOP)
        
        self.fileUrl = Entry(self.line5)
        self.fileUrl.insert(0,"File URL")
        self.fileUrl.configure(width=60)
        self.fileUrl.pack(side = LEFT)
        
    
    
    def generateUrlButton(self):
        publicKey  = self.publicKeyField.get()
        privateKey = self.privateKeyField.get()
        filePath   = self.filePathField.get()
        reqPayment = self.checkRequestPaymentVar.get()
        
        self.fileUrl.delete(0,END)
        self.fileUrl.insert(0,generateUrl(filePath, publicKey, privateKey, reqPayment))
    

root = Tk()
application = App(root)
root.mainloop()